package tests;

import static org.junit.Assert.*;

import java.lang.reflect.Field;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;

import entity.general.Pair;
import entity.general.MinTime;
import entity.main.Objective;
import entity.main.Task;
import entity.main.Task.TaskType;

public class TaskTest {

	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void testAddingTimeToday() {
		LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		task.addTimeSpent(new MinTime(3, 30));
		List <Pair <LocalDate, MinTime>> timeSpent = task.getTimeSpentOnTask();
		
		assertEquals(1, timeSpent.size());
		assertEquals(localDate, timeSpent.get(0).getFirst());
		assertEquals(new MinTime(3, 30), timeSpent.get(0).getSecond());
	}

	@Test
	public void testNextDayResetsTime() throws Exception
	{
		LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		task.addTimeSpent(new MinTime(3, 30));
		
		LocalDate firstDayDate = (new DateTime()).toLocalDate();
		firstDayDate = firstDayDate.minusDays(1);
		
		Field field = task.getClass().getDeclaredField("today");
		field.setAccessible(true);
		field.set(task, firstDayDate);

		task.init();
		task.addTimeSpent(new MinTime(5, 30));
		
		List <Pair <LocalDate, MinTime>> timeSpent = task.getTimeSpentOnTask();
		assertEquals(2, timeSpent.size());
		assertEquals(firstDayDate, timeSpent.get(0).getFirst());
		assertEquals(new MinTime(3, 30), timeSpent.get(0).getSecond());
		assertEquals(localDate, timeSpent.get(1).getFirst());
		assertEquals(new MinTime(5, 30), timeSpent.get(1).getSecond());
	}

	@Test
	public void testNextMonthResetsTime() throws Exception
	{
		LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		task.addTimeSpent(new MinTime(3, 30));
		
		LocalDate firstDayDate = (new DateTime()).toLocalDate();
		firstDayDate = firstDayDate.minusMonths(1);
		
		Field field = task.getClass().getDeclaredField("today");
		field.setAccessible(true);
		field.set(task, firstDayDate);

		task.init();
		task.addTimeSpent(new MinTime(5, 30));
		
		List <Pair <LocalDate, MinTime>> timeSpent = task.getTimeSpentOnTask();
		assertEquals(2, timeSpent.size());
		assertEquals(firstDayDate, timeSpent.get(0).getFirst());
		assertEquals(new MinTime(3, 30), timeSpent.get(0).getSecond());
		assertEquals(localDate, timeSpent.get(1).getFirst());
		assertEquals(new MinTime(5, 30), timeSpent.get(1).getSecond());
	}

	@Test
	public void testNextYearResetsTime() throws Exception
	{
		LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		task.addTimeSpent(new MinTime(3, 30));
		
		LocalDate firstDayDate = (new DateTime()).toLocalDate();
		firstDayDate = firstDayDate.minusYears(1);
		
		Field field = task.getClass().getDeclaredField("today");
		field.setAccessible(true);
		field.set(task, firstDayDate);

		task.init();
		task.addTimeSpent(new MinTime(5, 30));
		
		List <Pair <LocalDate, MinTime>> timeSpent = task.getTimeSpentOnTask();
		assertEquals(2, timeSpent.size());
		assertEquals(firstDayDate, timeSpent.get(0).getFirst());
		assertEquals(new MinTime(3, 30), timeSpent.get(0).getSecond());
		assertEquals(localDate, timeSpent.get(1).getFirst());
		assertEquals(new MinTime(5, 30), timeSpent.get(1).getSecond());
	}

	@Test
	public void testSameDayTimeAdd() throws Exception
	{
		LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		task.addTimeSpent(new MinTime(3, 30));
		task.addTimeSpent(new MinTime(3, 30));
		
		LocalDate firstDayDate = (new DateTime()).toLocalDate();
		firstDayDate = firstDayDate.minusMonths(1);
		
		Field field = task.getClass().getDeclaredField("today");
		field.setAccessible(true);
		field.set(task, firstDayDate);

		task.init();
		task.addTimeSpent(new MinTime(5, 30));
		
		List <Pair <LocalDate, MinTime>> timeSpent = task.getTimeSpentOnTask();
		assertEquals(2, timeSpent.size());
		assertEquals(firstDayDate, timeSpent.get(0).getFirst());
		System.out.println(new MinTime(7, 0) + ", " + timeSpent.get(0).getSecond());
		assertEquals(new MinTime(7, 0), timeSpent.get(0).getSecond());
		assertEquals(localDate, timeSpent.get(1).getFirst());
		assertEquals(new MinTime(5, 30), timeSpent.get(1).getSecond());
	}
	
	
	
	@Test
	public void testGetTimeSpentThisWeekDoesntIncludeEarlier() throws Exception
	{
		//LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		task.addTimeSpent(new MinTime(3, 30));
		
		LocalDate firstDayDate = (new DateTime()).toLocalDate();
		firstDayDate = firstDayDate.minusDays(8);
		
		Field field = task.getClass().getDeclaredField("today");
		field.setAccessible(true);
		field.set(task, firstDayDate);

		task.init();
		task.addTimeSpent(new MinTime(5, 30));

		assertEquals(new MinTime(5, 30), task.getTimeSpentOnTaskThisWeek());		
	}

	@Test
	public void testGetTimeSpentThisWeekDoesIncludeThisWeek() throws Exception
	{
		//System.out.println("TesT");
		//LocalDate localDate = (new DateTime()).toLocalDate();
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(10, 10));
		assertEquals(1, task.getTimeSpentOnTask().size());
		task.addTimeSpent(new MinTime(3, 30));
		assertEquals(1, task.getTimeSpentOnTask().size());
		
		LocalDate firstDayDate = (new DateTime()).toLocalDate();
		firstDayDate = firstDayDate.minusDays(6);
		
		Field field = task.getClass().getDeclaredField("today");
		field.setAccessible(true);
		field.set(task, firstDayDate);

		task.init();
		assertEquals(2, task.getTimeSpentOnTask().size());
		
		task.addTimeSpent(new MinTime(5, 30));

		assertEquals(new MinTime(9, 0), task.getTimeSpentOnTaskThisWeek());		
	}

	@Test
	public void testTimeSpentThisWeekAsPercentage() throws Exception
	{
		Task task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(0, 0));
		task.addTimeSpent(new MinTime(3, 30));
		assertEquals(1.0f, task.getTimeSpentThisWeekPercentage(), 0.01);

		task = new Task("Name", TaskType.GOAL, new Objective("Test"), new LocalDate(), "Description", new MinTime(1, 30));
		task.addTimeSpent(new MinTime(1, 10));
		assertEquals(0.778f, task.getTimeSpentThisWeekPercentage(), 0.01);
	}
	
}
